package com.zjuee.web.auth.service.impl;

import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.zjuee.base.bean.Pages;
import com.zjuee.base.bean.response.CommonResultCode;
import com.zjuee.base.constant.Common;
import com.zjuee.base.dto.common.auth.UserDto;
import com.zjuee.base.enums.UserStatus;
import com.zjuee.base.exception.BaseException;
import com.zjuee.base.exception.ServiceException;
import com.zjuee.base.model.AuthUser;
import com.zjuee.base.model.common.auth.User;
import com.zjuee.base.model.common.auth.UserRole;
import com.zjuee.base.utils.ZjueeUtil;
import com.zjuee.gateway.utils.EncryptUtil;
import com.zjuee.gateway.utils.RSAUtil;
import com.zjuee.gateway.utils.SecurityUtil;
import com.zjuee.service.auth.service.UserRoleService;
import com.zjuee.service.auth.service.UserService;
import com.zjuee.service.auth.vo.UserPasswordVo;
import com.zjuee.service.auth.vo.UserVo;
import com.zjuee.web.auth.enums.UserType;
import com.zjuee.web.auth.mapper.UserMapper;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.Date;
import java.util.Optional;

/**
 * 用户服务接口实现类
 *
 * @author wu liang
 * @since 1.0
 */
@Slf4j
@Service
public class UserServiceImpl implements UserService {

    @Resource
    private UserMapper userMapper;

    @Resource
    private UserRoleService userRoleService;

    @Value("${user.defaultPassword}")
    private String defaultPassword;


    @Override
    @Transactional
    public Long add(UserVo user) {
        checkUserParam(user);
        User select = selectByName(user.getName());
        if (null != select) {
            throw new ServiceException("The user already exists");
        }
        User userInfo = new User();
        //密码加密
        if(StringUtils.isEmpty(user.getPassword())){
            user.setPassword(defaultPassword);
        }
        String password = EncryptUtil.encryPasswrod(user.getName(), user.getPassword());
        userInfo.setPassword(password);
        AuthUser onlineUser = SecurityUtil.getOnlineUser();
        userInfo.setCreateId(onlineUser == null ? 0 : onlineUser.getCreateId());
        BeanUtils.copyProperties(user, userInfo);
        userInfo.setUserType(UserType.common.toString());
        userInfo.setOrgId(user.getOrgId());
        userInfo.setUserStatus(UserStatus.SUCCESS.getValue());
        userInfo.setLoginCount(0);
        userInfo.setGmtCreate(new Date());
        userInfo.setModifyId(userInfo.getCreateId());
        userInfo.setGmtModify(new Date());
        userInfo.setLastLoginIp("");
        userInfo.setLoginIp("");

        if (userMapper.insert(userInfo) > 0) {
            //用户注册时，默认赋予管理员角色
            UserRole userRole = new UserRole();
            userRole.setRoleId(user.getRoleId() == 0L ? 2L: user.getRoleId());
            userRole.setUserId(userInfo.getId());
            userRoleService.add(userRole);
            user.setId(userInfo.getId());
            user.setOrgId(userInfo.getOrgId());
            return user.getId();
        }
        throw new ServiceException("The user add failed");
    }

    @Override
    public boolean delete(Long id, Long orgId) {
        UserVo user = selectById(id, orgId);
        if (null == user) {
            throw new ServiceException("The user does not exist");
        }
        //同步删除该用户的赋予角色
        userRoleService.deleteByUserId(id);
        return userMapper.deleteById(id) > 0;
    }

    @Override
    public boolean update(UserVo user) {
        user.setName(null);
        User userInfo = new User();
        BeanUtils.copyProperties(user, userInfo);
        userInfo.setGmtModify(new Date());
//        userInfo.setModifyId(loginDto.getUserId());
        if(userMapper.updateById(userInfo) > 0){
            //若是角色id 存在则更新
            if(user.getRoleId() != null && user.getRoleId() > 0L){
                //获取id
                UserRole userRole = userRoleService.getUserRole(user.getId());
                if(userRole !=null && !StringUtils.equalsIgnoreCase(String.valueOf(user.getRoleId()), String.valueOf(userRole.getRoleId()))){
                    userRole.setRoleId(user.getRoleId());
                    userRoleService.update(userRole);
                }
            }
            return true;
        }
        throw new ServiceException("The user update failed");
    }

    @Override
    public UserVo selectById(Long id, Long orgId) {
        LambdaQueryWrapper<User> queryWrapper = Wrappers.<User>query().lambda();
        queryWrapper.eq(User::getId, id);
        User user = userMapper.selectOne(queryWrapper);
        UserVo userVo = new UserVo();
        BeanUtils.copyProperties(user, userVo);
        return userVo;
    }

    @Override
    public User selectByName(String name) {
        LambdaQueryWrapper<User> queryWrapper = Wrappers.<User>query().lambda()
                .eq(User::getName, name);
        return userMapper.selectOne(queryWrapper);
    }

    @Override
    public Page<UserVo> list(UserDto userDto) {
        if (!Optional.ofNullable(userDto.getPage()).isPresent()) {
            userDto.setPage(new Pages());
        }
        if (StringUtils.isNotBlank(userDto.getName())) {
            userDto.setName("%" + userDto.getName() + "%");
        }
        if (StringUtils.isNotBlank(userDto.getRealName())) {
            userDto.setRealName("%" + userDto.getRealName() + "%");
        }
        //需要关联查询
        return userMapper.findAllUserByOrgId(userDto.getPage().convert(), userDto);
    }

    @Override
    public boolean checkUserValid(String name) {
        User user = selectByName(name);
        if (null != user) {
            return user.getUserStatus() == UserStatus.LOCK.getValue();
        }
        return false;
    }

    @Override
    public boolean restPassword(Long id) {
        UserVo user = selectById(id, 0L);
        if (null != user) {
            user.setPassword(ZjueeUtil.md5(Common.DEFAULT_PASSWORD));
            return update(user);
        }
        return false;
    }

    /**
     * 修改用户密码
     */
    @Override
    @Transactional
    public Boolean updatePassword(String cipherText) {
        UserPasswordVo userPasswordVo = decryptUserStr(cipherText);
        if (userPasswordVo == null || userPasswordVo.getId() == null)
            throw new BaseException(CommonResultCode.CONSUMER_ERR, "用户id不能为空");
        if (StringUtils.isBlank(userPasswordVo.getNewPassword()))
            throw new BaseException(CommonResultCode.CONSUMER_ERR, "新密码不能为空");

        AuthUser onlineUser = SecurityUtil.getOnlineUser();
        if (ObjectUtil.notEqual(onlineUser.getId(),userPasswordVo.getId()))
            throw new BaseException(CommonResultCode.CONSUMER_ERR, "无此权限");

         //校验新密码
         if(!userPasswordVo.getNewPassword().matches(Common.RegExp.PASSWORD_REG)){
            throw new ServiceException("密码强度过低，需包含大写字母、小写字母、数字，长度8-15位");
        }

        //查询出用户信息
        User existUser = userMapper.selectById(userPasswordVo.getId());
        if (existUser == null)
            throw new BaseException(CommonResultCode.CONSUMER_ERR, "用户不存在");

        // 校验旧密码
        String oldPassword = EncryptUtil.encryPasswrod(existUser.getName(), userPasswordVo.getOldPassword());
        if (!oldPassword.equals(existUser.getPassword()))
            throw new BaseException(CommonResultCode.SYS_ERR, "原密码错误，修改失败！");

        // 设置新密码
        String newPassword = EncryptUtil.encryPasswrod(existUser.getName(), userPasswordVo.getNewPassword());
        existUser.setPassword(newPassword);
        existUser.setModifyId(SecurityUtil.getOnlineUser().getId());
        existUser.setGmtModify(new Date());
        userMapper.updateById(existUser);

        return true;
    }

    @Override
    public LambdaQueryWrapper<UserVo> fuzzyQuery(UserDto userDto) {
        LambdaQueryWrapper<UserVo> queryWrapper = Wrappers.<UserVo>query().lambda();
        Optional.ofNullable(userDto).ifPresent(dto -> {
            if (StringUtils.isNotBlank(dto.getName())) {
                queryWrapper.like(UserVo::getName, dto.getName());
            }
        });
        return queryWrapper;
    }

    //验证信息
    private void checkUserParam(UserVo userVo){
        if(!userVo.getName().matches(Common.RegExp.USERNAME_REG)){
            throw new ServiceException("invalid name");
        }
        if(!userVo.getPassword().matches(Common.RegExp.PASSWORD_REG)){
            throw new ServiceException("invalid password");
        }
        if(!userVo.getPhone().matches(Common.RegExp.MOBILE_STRICT)){
            throw new ServiceException("invalid phone");
        }
    }

    /**
     * 根据密文 解密user
     */
    private UserPasswordVo decryptUserStr(String cipherText){
        if (StringUtils.isBlank(cipherText))
            throw new BaseException(CommonResultCode.CONSUMER_ERR, "非法请求");
        String jsonStr = "";
        try {
            jsonStr = RSAUtil.privateDecrypt(cipherText, RSAUtil.getDefaultKey().getPrivateKeyStr());
        } catch (Exception e) {
            throw new BaseException(CommonResultCode.CONSUMER_ERR, "非法请求");
        }
        try {
            return JSONObject.parseObject(jsonStr, UserPasswordVo.class);
        } catch (Exception e) {
            throw new BaseException(CommonResultCode.CONSUMER_ERR, "非法请求");
        }
    }

}
